/*!
 * \file Allocator.h
 * \brief Memory allocator module.
 * \author Nus
 * \date 2008/02/16, 13:21
 */

#ifndef __ALLOCATOR_H__
#define __ALLOCATOR_H__

#include "Types.h"
#include "Mem.h"

/*!
 * \class Allocator
 * \brief Memory allocator.
 */
class Allocator
{
public:
  //! \brief Default constructor.
  Allocator();

  //! \brief Default destructor.
  virtual ~Allocator();
  
  //! \brief Allocate memory.
  virtual void* memAlloc(size_t size, s32 align = 32,
                         const s8* file_loc = NULL,
                         s32 line_loc = 0);

  //! \brief Deallocate memory.
  virtual void memFree(void* addr);
  
  //! \brief Dump memory info.
  virtual void dumpInfo(void) const;

  //! \brief Dump memory info (detailed version).
  virtual void dumpInfoEx(void) const;

  //! \brief Is empty.
  virtual bool isEmpty(void) const {
    return (mMemoryHandle.mem_chain == NULL) && (mMemoryHandle.used_memory == 0);
  }
  
  //! \brief Get used memory size.
  virtual u64 getUsedMemSize(void) const {
    return mMemoryHandle.used_memory;
  }
  
  //! \brief Get memory handle.
  sMemoryHandle* getMemHandle(void) {
    return &mMemoryHandle;
  }

protected:
  sMemoryHandle mMemoryHandle;    //!< Memory handle.

private:
  // None...

};



/*!
 * \class ChangeMemory
 * \brief Change memory handle.
 *
 * Use this class to temporarily change memory handle. Pass NULL
 * to change to default memory handle.
 */
class ChangeMemory
{
public:
  //! \brief Default constructor.
  ChangeMemory(sMemoryHandle* mem_handle = NULL)
      : mSaveHandle(NULL)
  {
    mSaveHandle = SetCurrentMemoryHandle(mem_handle);
  }
  
  //! \brief Constructor.
  ChangeMemory(Allocator* p_alloc) {
    mSaveHandle = SetCurrentMemoryHandle(p_alloc->getMemHandle());
  }

  //! \brief Destructor.
  virtual ~ChangeMemory() {
    SetCurrentMemoryHandle(mSaveHandle);
  }

protected:
  sMemoryHandle* mSaveHandle;

private:
  // None...

};

#endif
